//! 编码检测与国际化支持模块
//!
//! 提供HTML文档的编码检测、转换和国际化处理功能

// 临时替换encoding_rs库，使用内置实现
use once_cell::sync::Lazy;
use std::collections::HashMap;

/// 简化的编码结构，替代encoding_rs::Encoding
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Encoding {
    name: &'static str,
}

// 定义常用编码
pub const UTF_8: &Encoding = &Encoding { name: "UTF-8" };
pub const UTF_16BE: &Encoding = &Encoding { name: "UTF-16BE" };
pub const UTF_16LE: &Encoding = &Encoding { name: "UTF-16LE" };
pub const ISO_8859_1: &Encoding = &Encoding { name: "ISO-8859-1" };
pub const SHIFT_JIS: &Encoding = &Encoding { name: "Shift_JIS" };
pub const GBK: &Encoding = &Encoding { name: "GBK" };

impl Encoding {
    /// 获取编码名称
    pub fn name(&self) -> &'static str {
        self.name
    }

    /// 根据标签查找编码
    pub fn for_label(label: &[u8]) -> Option<&'static Encoding> {
        let label_str = std::str::from_utf8(label).ok()?;
        match label_str.to_ascii_lowercase().as_str() {
            "utf-8" | "utf8" => Some(UTF_8),
            "utf-16be" | "utf16be" => Some(UTF_16BE),
            "utf-16le" | "utf16le" => Some(UTF_16LE),
            "iso-8859-1" | "latin1" => Some(ISO_8859_1),
            "shift_jis" | "shift-jis" | "sjis" => Some(SHIFT_JIS),
            "gbk" | "gb2312" => Some(GBK),
            _ => None,
        }
    }

    /// 检测BOM字节序标记
    pub fn for_bom(bytes: &[u8]) -> Option<(&'static Encoding, usize)> {
        if bytes.starts_with(&[0xEF, 0xBB, 0xBF]) {
            Some((UTF_8, 3))
        } else if bytes.starts_with(&[0xFE, 0xFF]) {
            Some((UTF_16BE, 2))
        } else if bytes.starts_with(&[0xFF, 0xFE]) {
            Some((UTF_16LE, 2))
        } else {
            None
        }
    }
}

/// 编码检测器结构体
#[derive(Debug, Clone)]
pub struct EncodingDetector {
    /// 当前检测到的编码
    detected_encoding: Option<&'static Encoding>,
    /// 默认编码
    default_encoding: &'static Encoding,
    /// 是否从BOM检测到编码
    detected_from_bom: bool,
    /// 是否从元数据检测到编码
    detected_from_meta: bool,
    /// 检测到的置信度(0-100)
    confidence: u8,
}

impl Default for EncodingDetector {
    fn default() -> Self {
        Self {
            detected_encoding: Some(UTF_8),
            default_encoding: UTF_8,
            detected_from_bom: false,
            detected_from_meta: false,
            confidence: 0,
        }
    }
}

impl EncodingDetector {
    /// 创建新的编码检测器实例
    pub fn new() -> Self {
        Self::default()
    }

    /// 根据默认编码创建实例
    pub fn with_default_encoding(encoding_name: &str) -> Self {
        let default_enc = Encoding::for_label(encoding_name.as_bytes()).unwrap_or(UTF_8);

        Self {
            detected_encoding: Some(default_enc),
            default_encoding: default_enc,
            detected_from_bom: false,
            detected_from_meta: false,
            confidence: 0,
        }
    }

    /// 从字节流检测编码
    pub fn detect_from_bytes(&mut self, bytes: &[u8]) -> &'static Encoding {
        // 1. 尝试从BOM检测
        if let Some((encoding, _)) = Encoding::for_bom(bytes) {
            self.detected_encoding = Some(encoding);
            self.detected_from_bom = true;
            self.confidence = 100;
            return encoding;
        }

        // 2. 启发式检测 (简单实现，生产环境中可以使用更复杂的算法)
        // 检查UTF-8有效性
        if let Ok(_) = std::str::from_utf8(bytes) {
            self.detected_encoding = Some(UTF_8);
            self.confidence = 90;
            return UTF_8;
        }

        // 3. 如果无法确定，返回默认编码
        self.detected_encoding = Some(self.default_encoding);
        self.confidence = 50;
        self.default_encoding
    }

    /// 从HTML元数据中检测编码
    pub fn detect_from_meta(&mut self, html: &str) -> &'static Encoding {
        // 简单的元数据编码检测实现

        // 1. 查找 <meta charset="..."> 格式
        if let Some(pos) = html.to_lowercase().find("<meta charset=") {
            let end_pos = html[pos..].find(">").map(|p| p + pos).unwrap_or(html.len());
            let meta_tag = &html[pos..end_pos];

            // 提取编码名称
            if let Some(charset_pos) = meta_tag.find("charset=") {
                let charset_start = charset_pos + 8; // "charset=".len()
                let quote = meta_tag.chars().nth(charset_start).unwrap_or('"');

                let charset_value_start = if quote == '"' || quote == '\'' {
                    charset_start + 1
                } else {
                    charset_start
                };

                let charset_end = meta_tag[charset_value_start..]
                    .find(|c| c == '"' || c == '\'' || c == ' ' || c == '>')
                    .map(|p| p + charset_value_start)
                    .unwrap_or(meta_tag.len());

                let charset = meta_tag[charset_value_start..charset_end].trim();

                if let Some(encoding) = Encoding::for_label(charset.as_bytes()) {
                    self.detected_encoding = Some(encoding);
                    self.detected_from_meta = true;
                    self.confidence = 100;
                    return encoding;
                }
            }
        }

        // 2. 查找 <meta http-equiv="Content-Type" content="text/html; charset=..."> 格式
        if let Some(pos) = html
            .to_lowercase()
            .find("<meta http-equiv=\"content-type\"")
        {
            let end_pos = html[pos..].find(">").map(|p| p + pos).unwrap_or(html.len());
            let meta_tag = &html[pos..end_pos];

            if let Some(content_pos) = meta_tag.find("content=") {
                let content_start = content_pos + 8; // "content="
                let quote = meta_tag.chars().nth(content_start).unwrap_or('"');

                let content_value_start = if quote == '"' || quote == '\'' {
                    content_start + 1
                } else {
                    content_start
                };

                let content_end = meta_tag[content_value_start..]
                    .find(|c| c == '"' || c == '\'' || c == ' ' || c == '>')
                    .map(|p| p + content_value_start)
                    .unwrap_or(meta_tag.len());

                let content = meta_tag[content_value_start..content_end].trim();

                if let Some(charset_pos) = content.to_lowercase().find("charset=") {
                    let charset_start = charset_pos + 8; // "charset=".len()
                    let charset_end = content[charset_start..]
                        .find(|c| c == ';' || c == ' ')
                        .map(|p| p + charset_start)
                        .unwrap_or(content.len());

                    let charset = content[charset_start..charset_end].trim();

                    if let Some(encoding) = Encoding::for_label(charset.as_bytes()) {
                        self.detected_encoding = Some(encoding);
                        self.detected_from_meta = true;
                        self.confidence = 100;
                        return encoding;
                    }
                }
            }
        }

        // 3. 查找XML声明
        if html.starts_with("<?xml") {
            let end_pos = html.find("?>").unwrap_or(html.len());
            let xml_decl = &html[..end_pos];

            if let Some(encoding_pos) = xml_decl.find("encoding=") {
                let encoding_start = encoding_pos + 9; // "encoding=".len()
                let quote = xml_decl.chars().nth(encoding_start).unwrap_or('"');

                let encoding_value_start = if quote == '"' || quote == '\'' {
                    encoding_start + 1
                } else {
                    encoding_start
                };

                let encoding_end = xml_decl[encoding_value_start..]
                    .find(|c| c == '"' || c == '\'' || c == ' ' || c == '?')
                    .map(|p| p + encoding_value_start)
                    .unwrap_or(xml_decl.len());

                let encoding_name = xml_decl[encoding_value_start..encoding_end].trim();

                if let Some(encoding) = Encoding::for_label(encoding_name.as_bytes()) {
                    self.detected_encoding = Some(encoding);
                    self.detected_from_meta = true;
                    self.confidence = 100;
                    return encoding;
                }
            }
        }

        // 返回已检测的编码或默认编码
        self.detected_encoding.unwrap_or(self.default_encoding)
    }

    /// 获取检测到的编码
    pub fn get_detected_encoding(&self) -> &'static Encoding {
        self.detected_encoding.unwrap_or(self.default_encoding)
    }

    /// 获取检测到的编码名称
    pub fn get_encoding_name(&self) -> &'static str {
        self.get_detected_encoding().name()
    }

    /// 检查是否从BOM检测到编码
    pub fn is_detected_from_bom(&self) -> bool {
        self.detected_from_bom
    }

    /// 检查是否从元数据检测到编码
    pub fn is_detected_from_meta(&self) -> bool {
        self.detected_from_meta
    }

    /// 获取检测的置信度
    pub fn get_confidence(&self) -> u8 {
        self.confidence
    }
}

/// 国际化支持模块
#[derive(Debug)]
pub struct Internationalization {
    /// 语言特定的处理配置
    language_configs: HashMap<String, LanguageConfig>,
}

/// 语言特定配置
#[derive(Debug, Clone)]
pub struct LanguageConfig {
    /// 语言代码
    pub code: String,
    /// 文本方向 (ltr或rtl)
    pub direction: TextDirection,
    /// 主要字符集
    pub charset: &'static Encoding,
}

/// 文本方向枚举
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TextDirection {
    /// 从左到右
    LeftToRight,
    /// 从右到左
    RightToLeft,
}

impl Default for TextDirection {
    fn default() -> Self {
        TextDirection::LeftToRight
    }
}

impl Default for Internationalization {
    fn default() -> Self {
        let mut lang_configs = HashMap::new();

        // 添加一些常见语言的配置
        lang_configs.insert(
            "ar".to_string(),
            LanguageConfig {
                code: "ar".to_string(),
                direction: TextDirection::RightToLeft,
                charset: UTF_8,
            },
        );

        lang_configs.insert(
            "he".to_string(),
            LanguageConfig {
                code: "he".to_string(),
                direction: TextDirection::RightToLeft,
                charset: UTF_8,
            },
        );

        lang_configs.insert(
            "zh-CN".to_string(),
            LanguageConfig {
                code: "zh-CN".to_string(),
                direction: TextDirection::LeftToRight,
                charset: UTF_8,
            },
        );

        // 其他语言配置...

        Self {
            language_configs: lang_configs,
        }
    }
}

impl Internationalization {
    /// 创建新的国际化实例
    pub fn new() -> Self {
        Self::default()
    }

    /// 获取语言的文本方向
    pub fn get_text_direction(&self, lang_code: &str) -> TextDirection {
        // 简化的语言代码处理
        let simple_code = if lang_code.contains("-") || lang_code.contains("_") {
            lang_code.split(['-', '_']).next().unwrap_or(lang_code)
        } else {
            lang_code
        };

        // 查找语言配置
        if let Some(config) = self.language_configs.get(simple_code) {
            config.direction
        } else {
            // 默认从左到右
            TextDirection::LeftToRight
        }
    }

    /// 检查语言是否为RTL
    pub fn is_rtl_language(&self, lang_code: &str) -> bool {
        self.get_text_direction(lang_code) == TextDirection::RightToLeft
    }

    /// 解码HTML实体
    pub fn decode_html_entities(&self, text: &str) -> String {
        // 常见HTML实体映射
        static HTML_ENTITIES: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
            let mut map = HashMap::new();
            map.insert("&lt;", "<");
            map.insert("&gt;", ">");
            map.insert("&amp;", "&");
            map.insert("&quot;", "\"");
            map.insert("&apos;", "'");
            map.insert("&nbsp;", "\u{00A0}");
            map.insert("&copy;", "©");
            map.insert("&reg;", "®");
            map.insert("&trade;", "™");
            // 添加更多常见实体...
            map
        });

        let mut result = text.to_string();

        // 替换命名实体
        for (entity, character) in HTML_ENTITIES.iter() {
            result = result.replace(entity, character);
        }

        // 不使用regex库，简单实现十进制和十六进制实体解码
        let mut processed = String::with_capacity(result.len());
        let mut chars = result.chars().peekable();

        while let Some(c) = chars.next() {
            if c == '&' && chars.peek() == Some(&'#') {
                chars.next(); // 消费'#'
                let mut is_hex = false;

                // 检查是否是十六进制
                if let Some(&'x') | Some(&'X') = chars.peek() {
                    is_hex = true;
                    chars.next(); // 消费'x'或'X'
                }

                let mut value = String::new();
                let mut found_semicolon = false;

                // 收集数字
                while let Some(&next) = chars.peek() {
                    if next == ';' {
                        chars.next(); // 消费';'
                        found_semicolon = true;
                        break;
                    } else if (is_hex && next.is_ascii_hexdigit())
                        || (!is_hex && next.is_ascii_digit())
                    {
                        value.push(chars.next().unwrap());
                    } else {
                        break;
                    }
                }

                // 解析并转换为字符
                if found_semicolon && !value.is_empty() {
                    let code_point = if is_hex {
                        u32::from_str_radix(&value, 16).ok()
                    } else {
                        value.parse::<u32>().ok()
                    };

                    if let Some(cp) = code_point.and_then(std::char::from_u32) {
                        processed.push(cp);
                        continue;
                    }
                }

                // 解析失败，还原原始文本
                processed.push('&');
                processed.push('#');
                if is_hex {
                    processed.push('x');
                }
                processed.push_str(&value);
                if found_semicolon {
                    processed.push(';');
                }
            } else {
                processed.push(c);
            }
        }

        processed
    }
}
